package com.gitee.feizns.quickstart.caffeine;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.RequiredArgsConstructor;

import java.util.Collection;
import java.util.Iterator;
import java.util.Set;

/**
 * 缓存集
 * @author feizns
 * @since 2025/5/9
 */
@RequiredArgsConstructor
public class CacheSet<T> implements Set<T> {

    /**
     * 缓存
     */
    private final Cache<T, Object> cache;

    public static void main(String[] args) {
        CacheSet<String> set = new CacheSet<>(Caffeine.newBuilder().maximumSize(2).build());
        System.out.println(set.size());
        set.add("1");
        set.add("2");
        set.forEach(System.out::print);
        System.out.println();
        set.add("3");
        set.forEach(System.out::print);
        System.out.println();
    }

    @Override
    public int size() {
        return (int) cache.estimatedSize();
    }

    @Override
    public boolean isEmpty() {
        return cache.asMap().isEmpty();
    }

    @Override
    public boolean contains(Object o) {
        return cache.getIfPresent(o) != this;
    }

    @Override
    public Iterator<T> iterator() {
        return cache.asMap().keySet().iterator();
    }

    @Override
    public Object[] toArray() {
        return cache.asMap().keySet().toArray();
    }

    @Override
    public <T1> T1[] toArray(T1[] a) {
        return cache.asMap().keySet().toArray(a);
    }

    @Override
    public boolean add(T t) {
        cache.put(t, this);
        return true;
    }

    @Override
    public boolean remove(Object o) {
        cache.invalidate(o);
        return true;
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        for (Object o : c) {
            if ( !contains(o) )
                return false;
        }
        return true;
    }

    @Override
    public boolean addAll(Collection<? extends T> c) {
        c.forEach(this::add);
        return true;
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        cache.asMap().keySet().forEach(this::remove);
        return true;
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        c.forEach(this::remove);
        return true;
    }

    @Override
    public void clear() {
        cache.invalidateAll();
    }

}
